#include <iostream>
#include <map>
#include <memory>
#include <functional>


//个人浅解：
//模板函数. 参数为空, 返回值为void * 指针.
//将其当做std::string    、std::vector<> 、这样的类型就可以了。只不过其值为函数指针，但比函数指针更灵活。
//因为std::function  是一种模板，所以要传入类型，就如std::vector<int>  传入类型int一样
//不过,std::function传入的是函数类型  返回值 （参数类型） 如：std::function<void (int)>
#define FUNC function<void* (void)>

using namespace std;

class Reflector
{
private:
    map<std::string, FUNC> objectMap;  //保存对象名陈, 对象创建函数.
    static shared_ptr<Reflector> ptr;

public:
    void* CreateObject(const string &str)
    {
        for (auto & x : objectMap)
        {
            if(x.first == str)
                return x.second();
        }
        return nullptr;
    }

    void Register(const string &class_name, FUNC && generator)
    {
        objectMap[class_name] = generator;
    }

    static shared_ptr<Reflector> Instance()
    {
        if(ptr == nullptr)
        {
            ptr.reset(new Reflector());
        }

        return ptr;
    }

};

shared_ptr<Reflector> Reflector::ptr = nullptr;

// forward 推导实参的类型.
class RegisterAction
{
public:
    RegisterAction(const string &class_name, FUNC && generator)
    {
        std::cout << "RegisterAction: " << class_name << std::endl;
        Reflector::Instance()->Register(class_name, forward<FUNC>(generator));
    }
};


// c++ 中 单# 号代表的是将字符当成字符串处理, ## 代表的是连接符
// define REGISTER(CLASS_NAME)    RegisterAction g_register_action_##CLASS_NAME(类名称, 匿名函数名称)  定义类构造器
#define REGISTER(CLASS_NAME) \
RegisterAction g_register_action_##CLASS_NAME(#CLASS_NAME, []()\
{\
      std::cout << "g_register_action_" << #CLASS_NAME << std::endl;\
    return new CLASS_NAME(); \
});



class Base
{
public:
    explicit Base() = default;
    virtual void Print()
    {
        cout << "Base" << endl;
    }
};
REGISTER(Base);

class DeriveA : public Base
{
public:
    void Print() override
    {
        cout << "DeriveA" << endl;
    }
};
REGISTER(DeriveA);

class DeriveB : public Base
{
public:
    void Print() override
    {
        cout << "DeriveB" << endl;
    }
};
REGISTER(DeriveB);

int main()
{
    shared_ptr<Base> p1((Base*)Reflector::Instance()->CreateObject("Base"));
    p1->Print();

    shared_ptr<Base> p2((Base*)Reflector::Instance()->CreateObject("DeriveA"));
    p2->Print();


    shared_ptr<Base> p4((Base*)Reflector::Instance()->CreateObject("DeriveA"));
    p4->Print();

    std::cout << " " << p2 << " " << p4 << std::endl;

    shared_ptr<Base> p3((Base*)Reflector::Instance()->CreateObject("DeriveB"));
    p3->Print();
}







































































































